
module moduleName (
    addr,
    dat,
    rw,
    clk,
    rst,

    d_fromA,
    d_fromX,
    d_fromY,
    d_fromS,
    d_fromM,
    d_toA,
    d_toX,
    d_toY,
    d_toS,
    d_toM,
    d_fromP,
    d_toP,
    d_toDbusH,
    d_toDbusL,

    a_selDbus,
    a_setPC,
    a_setSP,

    a_incPC,
    a_incSP,
    a_incAddr,

    exec_status,
    set_exec_status,
);

`define EXEC_STATUS_WIDTH 'd7

    output wire[15:0] addr;
    inout wire[7:0] dat; assign dat=rw?'hzz:temp;
    output reg rw = 'd0;
    input wire clk;
    input wire rst;

    reg[15:0] cpu_addr; assign addr = cpu_addr;
    reg[15:0] PC;
    reg[15:0] DBus;

    reg[7:0] A = 'd0;
    reg[7:0] X = 'd0;
    reg[7:0] Y = 'd0;
    reg[7:0] S = 'd0;
    reg[7:0] P = 'd0;

    reg[7:0] temp = 'd0;

    output reg[`EXEC_STATUS_WIDTH:0] exec_status;
    input wire[`EXEC_STATUS_WIDTH:0] set_exec_status;


    input wire d_fromA;
    input wire d_fromX;
    input wire d_fromY;
    input wire d_fromS;
    input wire d_fromM;
    input wire d_fromP;
    input wire d_toP;
    input wire d_toA;
    input wire d_toX;
    input wire d_toY;
    input wire d_toS;
    input wire d_toM;
    input wire d_toDbusH;
    input wire d_toDbusL;
    input wire a_selDbus;
    input wire a_setPC;
    input wire a_setSP;

    input wire a_incPC;
    input wire a_incSP;
    input wire a_incAddr;

    wire [7:0] addr_inc_v = 'd1;
    wire [15:0] cpu_addr_inc = cpu_addr + addr_inc_v;

    reg set_rw = 'b1;

    always @(*) begin
        if(d_fromA&exec_status[2]) temp = A;
        if(d_fromX&exec_status[2]) temp = X;
        if(d_fromY&exec_status[2]) temp = Y;
        if(d_fromS&exec_status[2]) temp = S;
        if(d_fromM&exec_status[2]) temp = dat;
        if(d_fromP&exec_status[2]) temp = P;
    end

    always @(*) begin
        if(d_toA&exec_status[1]) A = temp;
        if(d_toX&exec_status[1]) X = temp;
        if(d_toY&exec_status[1]) Y = temp;
        if(d_toS&exec_status[1]) S = temp;
        if(d_toP&exec_status[1]) P = temp;
        if(d_toM&exec_status[1]) begin set_rw <= 'b0; end

        if(a_incAddr) cpu_addr = cpu_addr + 16'd1;
        if(a_incPC)   PC = cpu_addr;
        if(a_incSP)   S =  cpu_addr[7:0];

        if(d_toDbusL) DBus[7:0] = temp;
        if(d_toDbusH) DBus[7:0] = temp;
        if(a_selDbus) cpu_addr = DBus;
        if(a_setPC)   cpu_addr = PC;
        if(a_setSP)   cpu_addr = {8'h01,S};
    end


    always @(negedge clk ) begin
        if(~set_rw)begin rw<='b0; end
        if(~rw)begin rw<='b1; end       //上一个状态为写入
        if(exec_status=='d0)begin exec_status <= set_exec_status; end
        else exec_status <= {1'b0,exec_status[`EXEC_STATUS_WIDTH:1]};
    end

endmodule